package com.example.composemodifiterdemo

import android.annotation.SuppressLint
import android.graphics.RuntimeShader
import android.os.Build
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.annotation.RequiresApi
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.draw.drawWithCache
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.geometry.center
import androidx.compose.ui.graphics.*
import androidx.compose.ui.graphics.drawscope.inset
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.imageResource
import androidx.compose.ui.text.ExperimentalTextApi
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import org.intellij.lang.annotations.Language

/**
 * @auth: njb
 * @date: 2023/1/3 23:22
 * @desc:
 */
class BrushActivity:ComponentActivity() {
    @SuppressLint("NewApi")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            drawCircle()
           // ShaderBrushExample()
        }
    }

    @Preview
    @OptIn(ExperimentalTextApi::class)
    @Composable
    fun drawCircle(){
        val brush = Brush.horizontalGradient(listOf(Color.Red, Color.Blue))
        Canvas(
            modifier = Modifier.size(200.dp),
            onDraw = {
                drawCircle(brush)
            }
        )
        val colorStops = arrayOf(
            0.0f to Color.Yellow,
            0.2f to Color.Red,
            1f to Color.Blue
        )
        Box(
            modifier = Modifier
                .requiredSize(200.dp)
                .background(Brush.horizontalGradient(colorStops = colorStops))
        )

        val listColors = listOf(Color.Yellow, Color.Red, Color.Blue)
        val tileSize = with(LocalDensity.current) {
            50.dp.toPx()
        }
        Box(
            modifier = Modifier
                .requiredSize(200.dp)
                .background(
                    Brush.horizontalGradient(
                        listColors,
                        endX = tileSize,
                        tileMode = TileMode.Repeated
                    )
                )
        )

        val customBrush = remember {
            object : ShaderBrush() {
                override fun createShader(size: Size): Shader {
                    return LinearGradientShader(
                        colors = listColors,
                        from = Offset.Zero,
                        to = Offset(size.width / 4f, 0f),
                        tileMode = TileMode.Mirror
                    )
                }
            }
        }
        Box(
            modifier = Modifier
                .requiredSize(200.dp)
                .background(customBrush)
        )

        Box(
            modifier = Modifier
                .fillMaxSize()
                .background(
                    Brush.radialGradient(
                        listOf(Color(0xFF2be4dc), Color(0xFF243484))
                    )
                )
        )

        val largeRadialGradient = object : ShaderBrush() {
            override fun createShader(size: Size): Shader {
                val biggerDimension = maxOf(size.height, size.width)
                return RadialGradientShader(
                    colors = listOf(Color(0xFF2be4dc), Color(0xFF243484)),
                    center = size.center,
                    radius = biggerDimension / 2f,
                    colorStops = listOf(0f, 0.95f)
                )
            }
        }

        Box(
            modifier = Modifier
                .fillMaxSize()
                .background(largeRadialGradient)
        )

        val colorStops1 = arrayOf(
            0.0f to Color.Yellow,
            0.2f to Color.Red,
            1f to Color.Blue
        )
        val brush1 = Brush.horizontalGradient(colorStops = colorStops1)
        Box(
            modifier = Modifier
                .requiredSize(200.dp)
                .drawBehind {
                    drawRect(brush = brush1) // will allocate a shader to occupy the 200 x 200 dp drawing area
                    inset(10f) {
                        /* Will allocate a shader to occupy the 180 x 180 dp drawing area as the
                         inset scope reduces the drawing  area by 10 pixels on the left, top, right,
                        bottom sides */
                        drawRect(brush = brush1)
                        inset(5f) {
                            /* will allocate a shader to occupy the 170 x 170 dp drawing area as the
                             inset scope reduces the  drawing area by 5 pixels on the left, top,
                             right, bottom sides */
                            drawRect(brush = brush1)
                        }
                    }
                }
        )

        val imageBrush =
            ShaderBrush(ImageShader(ImageBitmap.imageResource(id = R.mipmap.avatar)))

// Use ImageShader Brush with background
        Box(
            modifier = Modifier
                .requiredSize(200.dp)
                .background(imageBrush)
        )

// Use ImageShader Brush with TextStyle
        Text(
            text = "Hello Android!",
            style = TextStyle(
                brush = imageBrush,
                fontWeight = FontWeight.ExtraBold,
                fontSize = 36.sp
            )
        )

// Use ImageShader Brush with TextStyle
        Text(
            text = "Hello Android!",
            style = TextStyle(
                brush = imageBrush,
                fontWeight = FontWeight.ExtraBold,
                fontSize = 36.sp
            )
        )

// Use ImageShader Brush with DrawScope#drawCircle()
        Canvas(onDraw = {
            drawCircle(imageBrush)
        }, modifier = Modifier.size(200.dp))
    }

    val Coral = Color(0xFFF3A397)
    val LightYellow = Color(0xFFF8EE94)



    @RequiresApi(Build.VERSION_CODES.TIRAMISU)
    @Composable
    @Preview
    fun ShaderBrushExample() {
        Box(
            modifier = Modifier
                .drawWithCache {
                    val shader = RuntimeShader("AGSL")
                    val shaderBrush = ShaderBrush(shader)
                    shader.setFloatUniform("resolution", size.width, size.height)
                    onDrawBehind {
                        shader.setColorUniform(
                            "color",
                            android.graphics.Color.valueOf(
                                LightYellow.red, LightYellow.green,
                                LightYellow
                                    .blue,
                                LightYellow.alpha
                            )
                        )
                        shader.setColorUniform(
                            "color2",
                            android.graphics.Color.valueOf(
                                Coral.red,
                                Coral.green,
                                Coral.blue,
                                Coral.alpha
                            )
                        )
                        drawRect(shaderBrush)
                    }
                }
                .fillMaxWidth()
                .height(200.dp)
        )
    }
}